cmake_minimum_required(VERSION 3.5)
project(yvm) # 项目名称

set(CMAKE_CXX_STANDARD 14) # 使用 C++ 14 标准编译
if(UNIX)
    set(CMAKE_EXE_LINKER_FLAGS "-lpthread")
endif()

set(Boost_DEBUG on) # 是否开启 Boost Debug 模式，ON位开启，OFF关闭。开启之后会输出很多调试信息，方便寻找错误

# 实践生成少一个数字“1”和多一个“-x64”
# Searching for PROGRAM_OPTIONS_LIBRARY_RELEASE: boost_program_options-mgw81-mt-1_77;
# G:\boost_1_77_0\stage\lib\libboost_program_options-mgw8-mt-x64-1_77.a
# https://www.it1352.com/1973843.html
# 如果使用 Visual Studio 2019 开发工具安装的 boost，就使用 Visual Studio 2019 打开项目，-mgw8 -x64 就不需要了。
# VS工具安装boost：https://blog.csdn.net/Mr_LiShao/article/details/118213236
set(Boost_COMPILER -mgw8)
set(Boost_ARCHITECTURE -x64)

# YOU *SHOULD* CHANGE THESE OPTIONS TO ADAPT YOUR ENVIRONMENT
# BOOST LIBRARY
# 具体配置说明参见：https://cmake.org/cmake/help/latest/module/FindBoost.html
set(Boost_USE_STATIC_LIBS        ON)  # 设置为 ON 以强制使用静态库。默认为OFF。
set(Boost_USE_MULTITHREADED      ON)  # 设置为 OFF 以使用非多线程库（“mt”标签）。默认为 ON。
set(BOOST_ROOT G:/boost_1_77_0)
# find_package(Boost COMPONENTS system filesystem program_options)  # 查找 Boost 包括目录和库
find_package(Boost COMPONENTS program_options)  # 只用到了 program_options 库

# 如果找到头文件和请求的库，则为真。
if(Boost_FOUND)
    include_directories(${Boost_INCLUDE_DIRS})    # 添加头文件搜索路径 set(BOOST_INCLUDEDIR ${BOOST_ROOT})
    # 将源代码添加到此项目的可执行文件。
    # add_executable (yvm "src/vm/Main.cpp"  "src/classfile/AccessFlag.h" "src/classfile/ClassFile.h" "src/classfile/FileReader.h" "src/gc/Concurrent.cpp" "src/gc/Concurrent.hpp" "src/gc/GC.cpp" "src/gc/GC.h" "src/interpreter/CallSite.cpp" "src/interpreter/CallSite.h" "src/interpreter/Internal.h" "src/interpreter/Interpreter.cpp" "src/interpreter/Interpreter.hpp" "src/interpreter/MethodResolve.cpp" "src/interpreter/MethodResolve.h" "src/interpreter/SymbolicRef.cpp" "src/interpreter/SymbolicRef.h" "src/misc/Debug.cpp" "src/misc/Debug.h" "src/misc/NativeMethod.cpp" "src/misc/NativeMethod.h" "src/misc/Option.h" "src/misc/Utils.cpp" "src/misc/Utils.h" "src/runtime/JavaClass.cpp" "src/runtime/JavaClass.h" "src/runtime/JavaException.cpp" "src/runtime/JavaException.h" "src/runtime/JavaFrame.cpp" "src/runtime/JavaFrame.hpp" "src/runtime/JavaHeap.cpp" "src/runtime/JavaHeap.hpp" "src/runtime/JavaType.h" "src/runtime/MethodArea.cpp" "src/runtime/MethodArea.h" "src/runtime/ObjectMonitor.cpp" "src/runtime/ObjectMonitor.h" "src/runtime/RuntimeEnv.cpp" "src/runtime/RuntimeEnv.h" "src/vm/Main.cpp" "src/vm/YVM.cpp" "src/vm/YVM.h")
    # 将源文件的名字保存在变量 SOURCE_FILES 中
    set(SOURCE_FILES src/vm/Main.cpp src/runtime/MethodArea.cpp src/runtime/JavaFrame.hpp src/runtime/JavaFrame.cpp src/classfile/ClassFile.h src/classfile/AccessFlag.h src/runtime/RuntimeEnv.cpp src/misc/NativeMethod.h
            src/interpreter/Interpreter.cpp src/interpreter/SymbolicRef.cpp src/misc/Debug.cpp src/runtime/JavaClass.cpp src/runtime/JavaHeap.cpp src/runtime/JavaHeap.hpp src/interpreter/Interpreter.hpp src/interpreter/MethodResolve.cpp
            src/misc/NativeMethod.cpp src/vm/YVM.cpp src/misc/Utils.h src/misc/Utils.cpp src/runtime/JavaException.h src/runtime/JavaException.cpp src/runtime/ObjectMonitor.h
            src/runtime/ObjectMonitor.cpp src/gc/GC.h src/gc/GC.cpp src/misc/Option.h src/gc/Concurrent.hpp src/gc/Concurrent.cpp src/interpreter/Internal.h src/interpreter/CallSite.cpp)
    add_executable(yvm ${SOURCE_FILES})
    link_directories(... ${Boost_LIBRARY_DIRS})   # 添加库文件搜索路径 link_directories(G:/boost_1_77_0/stage/lib)
    target_link_libraries(yvm ${Boost_LIBRARIES}) # Boost_LIBRARIES 为 find_package 自动生成的变量
    if(UNIX)
        target_link_libraries(yvm lpthread)
    endif()
endif()


enable_testing()
file(GLOB test_file_name ${PROJECT_SOURCE_DIR}/javaclass/ydk/test/*.java)

if(WIN32)
    # adhoc tests
    add_test(NAME test_help COMMAND yvm --help)

    # automatically detected tests
    foreach(each_file ${test_file_name})
        string(REGEX REPLACE ".*/(.*)\.java" "\\1" curated_name ${each_file})
        add_test(NAME test_${curated_name} COMMAND yvm --runtime=${PROJECT_SOURCE_DIR}/bytecode "ydk.test.${curated_name}")
    endforeach(each_file ${test_file_name})
endif()
